﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InductBase;
using SharpBolt.Basics;
using SharpBolt.Graphics;
using SharpBolt.BasicIntefaces;

namespace SharpBolt.Graphics
{
    public class Painter
    {
        IGraphicRender Render;
        Vec2 defScale = new Vec2(1, 1);
        Vec2 defPosition = new Vec2(0, 0);
        double defRotation = 0;
        Color defColor = Colors.White;

        public Painter(IGraphicRender render)
        {
            Render = render;
        }

        public void DrawBitmap(SbBitmap bitmap)
        {
            DrawBitmap(bitmap, defPosition);
        }

        public void DrawBitmap(SbBitmap bitmap, Vec2 position)
        {
            DrawBitmap(bitmap, new Transformation(position, new Vec2(1, 1), Vec2.Null), defColor, Rec.FromLocationSize(Vec2.Null, bitmap.Size));
        }

        public void DrawBitmap(SbBitmap bitmap, Transformation transformation)
        {
            DrawBitmap(bitmap, transformation, defColor, Rec.FromLocationSize(Vec2.Null, bitmap.Size));
        }

        public void DrawBitmap(SbBitmap bitmap, Vec2 position, Color color)
        {
            DrawBitmap(bitmap, new Transformation(position, new Vec2(1, 1), Vec2.Null), color, Rec.FromLocationSize(Vec2.Null, bitmap.Size));
        }

        public void DrawBitmap(SbBitmap bitmap, Transformation transformation, Color color)
        {
            DrawBitmap(bitmap, transformation, color, Rec.FromLocationSize(Vec2.Null, bitmap.Size));
        }

        public void DrawBitmap(SbBitmap bitmap, Transformation transformation, Color color, Rec blit)
        {

            Render.Draw(bitmap, transformation.Position, transformation.Scale, transformation.Shift, transformation.Rotation, color, blit);
        }

        public void BeginDraw() { Render.BeginDraw(); }
        public void EndDraw() { Render.EndDraw(); }

        public void CenterDraw(SbBitmap bitmap, Vec2 center, Vec2 scale, double rotation, Color color, Rec blit)
        {

        }

        public void DecenterDraw(SbBitmap bitmap, Vec2 position, Vec2 center, Vec2 scale, double rotation, Color color, Rec blit) { }

        public void StretchDraw(SbBitmap bitmap, Rec bounds)
        {
            StretchDraw(bitmap, bounds, Colors.White);
        }
        public void StretchDraw(SbBitmap bitmap, Rec bounds, Color color)
        {
            StretchDraw(bitmap, bounds, color, new Rec(0, 0, bitmap.Size.X, bitmap.Size.Y));
        }
        public void StretchDraw(SbBitmap bitmap, Rec bounds, Color color, Rec blit)
        {
            DrawBitmap(bitmap, new Transformation(bounds.Location, bounds.Size / blit.Size, Vec2.Null, 0), color, blit);
        }

        public void DrawBorders(SbBitmap pattern, Rec area, Vec2 margin, Color color)
        {
            Vec2 src_size = pattern.Size;
            double marg_x = margin.X;
            double marg_y = margin.Y;

            //StretchDraw(pattern, area, Colors.Red, new Rec(0, 0, src_size.X, src_size.Y));

            Rec src_tl = Rec.FromLocationSize(Vec2.Null, margin);
            Rec dst_tl = Rec.FromLocationSize(area.Location, margin);

            Rec src_tr = Rec.FromLocationSize(new Vec2(src_size.X - marg_x, 0), margin);
            Rec dst_tr = Rec.FromLocationSize(area.Location + new Vec2(area.Size.X - marg_x, 0), margin);

            Rec src_bl = Rec.FromLocationSize(new Vec2(0, src_size.Y - marg_y), margin);
            Rec dst_bl = Rec.FromLocationSize(area.Location + new Vec2(0, area.Size.Y - marg_y), margin);

            Rec src_br = Rec.FromLocationSize(new Vec2(src_size.X - marg_x, src_size.Y - marg_y), margin);
            Rec dst_br = Rec.FromLocationSize(area.Location + new Vec2(area.Size.X - marg_x, area.Size.Y - marg_y), margin);

            StretchDraw(pattern, dst_tl, color, src_tl);
            StretchDraw(pattern, dst_tr, color, src_tr);
            StretchDraw(pattern, dst_bl, color, src_bl);
            StretchDraw(pattern, dst_br, color, src_br);

            Rec src_ml = new Rec(0, marg_y, marg_x, src_size.Y - 2 * marg_y);
            Rec dst_ml = new Rec(0, marg_y, marg_x, area.Size.Y - 2 * marg_y);
            dst_ml.Location += area.Location;
            StretchDraw(pattern, dst_ml, color, src_ml);

            Rec src_mr = new Rec(src_size.X - marg_x, marg_y, marg_x, src_size.Y - 2 * marg_y);
            Rec dst_mr = new Rec(area.Size.X - marg_x, marg_y, marg_x, area.Size.Y - 2 * marg_y);
            dst_mr.Location += area.Location;
            StretchDraw(pattern, dst_mr, color, src_mr);

            Rec src_mm = Rec.FromLocationSize(margin, src_size - 2 * margin);
            Rec dst_mm = Rec.FromLocationSize(margin, area.Size - 2 * margin);
            dst_mm.Location += area.Location;
            StretchDraw(pattern, dst_mm, color, src_mm);

            Rec src_tm = new Rec(marg_x, 0, src_size.X - 2 * marg_x, marg_y);
            Rec dst_tm = new Rec(marg_x, 0, area.Size.X - 2 * marg_x, marg_y);
            dst_tm.Location += area.Location;
            StretchDraw(pattern, dst_tm, color, src_tm);

            Rec src_bm = new Rec(marg_x, src_size.Y - marg_y, src_size.X - 2 * marg_x, marg_y);
            Rec dst_bm = new Rec(marg_x, area.Size.Y - marg_y, area.Size.X - 2 * marg_x, marg_y);
            dst_bm.Location += area.Location;
            StretchDraw(pattern, dst_bm, color, src_bm);
        }

        public void DrawTiled(SbBitmap pattern, Rec area, Color color)
        {
            DrawTiled(pattern, area, color, Vec2.Null);
        }

        public void DrawTiled(SbBitmap pattern, Rec area, Color color, Vec2 shift)
        {
            area = area.Copy();
            shift = shift % (Vec2)pattern.Size;

            for (int i = -1; i < area.Width / pattern.Size.X + 2; i++)
                for (int j = -1; j < area.Height / pattern.Size.Y + 2; j++)
                {
                    Vec2 pos = new Vec2(i * pattern.Size.X, j * pattern.Size.Y) + shift;
                    Vec2 size = pattern.Size;
                    Vec2 blitpos = Vec2.Null;

                    if (pos.X < 0)
                    {
                        blitpos.X = - pos.X;
                        size.X = size.X - blitpos.X;
                        pos.X = 0;
                    }

                    if (pos.Y < 0)
                    {
                        blitpos.Y = - pos.Y;
                        size.Y = size.Y - blitpos.Y;
                        pos.Y = 0;
                    }

                    if (pos.X + size.X > area.Width)
                    {
                        size.X = area.Width - pos.X;
                    }

                    if (pos.Y + size.Y > area.Height)
                    {
                        size.Y = area.Height - pos.Y;
                    }

                    Transformation trans = Transformation.Default;
                    trans.Position = area.Location + pos;

                    Rec blit = Rec.FromLocationSize(blitpos, size);
                    DrawBitmap(pattern, trans, color, blit);
                }
        }

        public void DrawBordersByInners(SbBitmap pattern, Rec area, Rec inners, Color color)
        {
            inners = inners.Copy();
            Vec2 size = area.Size;

            Rec tl = new Rec(0, 0, inners.X, inners.Y);
            Rec tt = new Rec(inners.X, 0, inners.Width, inners.Y);
            Rec tr = new Rec(inners.X + inners.Width, 0, pattern.Size.X - (inners.X + inners.Width), inners.Y);

            Rec ml = new Rec(0, inners.Y, inners.X, inners.Height);
            Rec mm = new Rec(inners.X, inners.Y, inners.Width, inners.Height);
            Rec mr = new Rec(inners.X + inners.Width, inners.Y, pattern.Size.X - (inners.X + inners.Width), inners.Height);

            Rec bl = new Rec(0, inners.Y + inners.Height, inners.X, pattern.Size.Y - (inners.Y + inners.Height));
            Rec bb = new Rec(inners.X, inners.Y + inners.Height, inners.Width, pattern.Size.Y - (inners.Y + inners.Height));
            Rec br = new Rec(inners.X + inners.Width, inners.Y + inners.Height, pattern.Size.X - (inners.X + inners.Width), pattern.Size.Y - (inners.Y + inners.Height));

            //=================

            Rec dinners = Rec.FromLocationSize(
                inners.Location,
                new Vec2(
                    size.X - (pattern.Size.X - inners.Width),
                    size.Y - (pattern.Size.Y - inners.Height)
                    ));

            inners = dinners;
            Rec dtl = new Rec(area.X + 0, area.Y + 0, inners.X, inners.Y);
            Rec dtt = new Rec(area.X + inners.X, area.Y + 0, inners.Width, inners.Y);
            Rec dtr = new Rec(area.X + inners.X + inners.Width, area.Y + 0, size.X - (inners.X + inners.Width), inners.Y);

            Rec dml = new Rec(area.X + 0, area.Y + inners.Y, inners.X, inners.Height);
            Rec dmm = new Rec(area.X + inners.X, area.Y + inners.Y, inners.Width, inners.Height);
            Rec dmr = new Rec(area.X + inners.X + inners.Width, area.Y + inners.Y, size.X - (inners.X + inners.Width), inners.Height);

            Rec dbl = new Rec(area.X + 0, area.Y + inners.Y + inners.Height, inners.X, size.Y - (inners.Y + inners.Height));
            Rec dbb = new Rec(area.X + inners.X, area.Y + inners.Y + inners.Height, inners.Width, size.Y - (inners.Y + inners.Height));
            Rec dbr = new Rec(area.X + inners.X + inners.Width, area.Y + inners.Y + inners.Height, size.X - (inners.X + inners.Width), size.Y - (inners.Y + inners.Height));
            //=============

            StretchDraw(pattern, dmm, color, mm);

            StretchDraw(pattern, dml, color, ml);
            StretchDraw(pattern, dmr, color, mr);

            StretchDraw(pattern, dtt, color, tt);
            StretchDraw(pattern, dbb, color, bb);

            StretchDraw(pattern, dtl, color, tl);
            StretchDraw(pattern, dtr, color, tr);

            StretchDraw(pattern, dbl, color, bl);
            StretchDraw(pattern, dbr, color, br);

            //StretchDraw(pattern, new Rec(0, 0, size.X, size.Y));
        }

    }
}
